#ifndef PRUEBAMANEJADORBITS_H_
#define PRUEBAMANEJADORBITS_H_

#define private public

#include <iostream>
#include "../ManejadorBits.h"
#include "../funciones.h"

using namespace Toolkit;
using namespace std;

bool pruebaEstaOverflow()
{
	bool resultadoPrueba = true;

	ManejadorBits manejadorBits;

	unsigned int techo = 3;
	unsigned int piso = 1;

	resultadoPrueba = resultadoPrueba && manejadorBits.estaOverflow(techo, piso);

	techo = techo << 30;

	resultadoPrueba = resultadoPrueba && (!manejadorBits.estaOverflow(techo, piso));

	piso = piso << 31;

	resultadoPrueba = resultadoPrueba && (manejadorBits.estaOverflow(techo, piso));

	if (!resultadoPrueba)
	{
		cout << "error en prueba estaOverflow";
	}

	return resultadoPrueba;
}

bool pruebaEstaUnderflow()
{
	bool resultadoPrueba = true;

	ManejadorBits manejadorBits;
	unsigned int techo = 1;
	unsigned int piso = 3;

	resultadoPrueba = resultadoPrueba && (!manejadorBits.estaUnderflow(techo, piso));

	techo = techo << 31;

	resultadoPrueba = resultadoPrueba && (!manejadorBits.estaUnderflow(techo, piso));

	piso = piso << 29;

	resultadoPrueba = resultadoPrueba && (manejadorBits.estaUnderflow(techo, piso));

	if (!resultadoPrueba)
	{
		cout << "error en prueba estaUnderflow";
	}

	return resultadoPrueba;
}

bool pruebaManejarOverflow()
{
	bool resultadoPrueba = true;

	ManejadorBits manejadorBits;
	unsigned int techo = 0;
	unsigned int piso = 0;

	manejadorBits.manejarOverflow(techo, piso);

	unsigned int maximo = ~0;

	resultadoPrueba = ((piso == 0) && (maximo == techo));

	piso = 1;
	piso = piso << 31;
	piso += 1;

	manejadorBits.manejarOverflow(techo, piso); //111...111 con 100..001

	resultadoPrueba = ((piso == 2) && (maximo == techo));

	if (!resultadoPrueba)
	{
		cout << "error en prueba manejarOverflow";
	}
	return resultadoPrueba;
}

bool pruebaManejarUnderflow()
{
	bool resultadoPrueba = true;

	ManejadorBits manejadorBits;
	unsigned int techo = 1;
	unsigned int piso = 1;

	techo = techo << 31;
	piso = piso << 30;

	unsigned int valorAux = techo;

	manejadorBits.manejarUnderflow(techo, piso);

	resultadoPrueba = ((techo == (valorAux + 1)) && (piso == 0));

	if (!resultadoPrueba)
	{
		cout << "error en prueba manejarUnderflow";
	}

	return resultadoPrueba;
}

bool pruebaProcesarBits()
{
	bool resultadoPrueba = true;

	ManejadorBits manejadorBits;
	unsigned int techo = 3;
	unsigned int piso = 5;

	techo = techo << 30;//110..000
	piso = piso << 29;//101..000

	techo += 3;
	piso += 2;

	manejadorBits.procesar(techo, piso);

	unsigned int techoPrueba = 1;

	techoPrueba = techoPrueba << 31;
	techoPrueba += 15;

	resultadoPrueba = ((piso == 8) && (techoPrueba == techo));

	if (!resultadoPrueba)
	{
		cout << "error en prueba procesarBits";
	}

	return resultadoPrueba;
}

bool pruebaEmitir()
{
	bool resultadoPrueba = true;
	ManejadorBits manejadorBits;
	unsigned int numero = 15;
	manejadorBits.emitir(numero, 32);

	int vector[8];

	for(unsigned int j = 0; j < manejadorBits.emision.size(); j++)
	{
		charToBits(manejadorBits.emision[j], vector);

		if (((j < 28) && (manejadorBits.emision[j] != 0)) ||
			((j >= 28) && (manejadorBits.emision[j] != 1)))
		{
			resultadoPrueba = false;
		}
	}

	string emision = manejadorBits.getEmision();
	charToBits(emision[3], vector);

	for(int i = 0; i < 8; i++)
	{
		if ((i > 3) && (vector[i] != 1))
		{
			resultadoPrueba = false;
		}
	}

	if (!resultadoPrueba)
	{
		cout << "error emitir";
	}

	return resultadoPrueba;
}

bool pruebaCompactarVentana()
{
	bool resultadoPrueba = true;
	ManejadorBits manejadorBits;

	unsigned int max = ~0;
	unsigned int aux1 = 1;
	unsigned int aux2 = aux1 << 30;
	aux1 <<= 31;

	max -= aux2;
	max -= aux1;

	manejadorBits.imprimirBits(max);

	manejadorBits.contadorOverflow = 1;
	//manejadorBits.contadorUnderflow = 4;

	cout << endl << "resultado de compactar: " ;
	unsigned cantidadBits = manejadorBits.compactarVentana(max);
	manejadorBits.imprimirBits(max);
	cout << endl << "cantidadBits: " << cantidadBits ;
	return resultadoPrueba;
}

void pruebaGeneralManejadorBits()
{
	bool resultadoPrueba = true;

	resultadoPrueba = resultadoPrueba && pruebaEstaOverflow();
	resultadoPrueba = resultadoPrueba && pruebaEstaUnderflow();
	resultadoPrueba = resultadoPrueba && pruebaManejarOverflow();
	resultadoPrueba = resultadoPrueba && pruebaManejarUnderflow();
	resultadoPrueba = resultadoPrueba && pruebaProcesarBits();
	resultadoPrueba = resultadoPrueba && pruebaEmitir();

	if (resultadoPrueba)
	{
		cout << "OK manejadorBits";
	} else {
		cout << "kaput";
	}
}

void pruebaObtenerBit()
{
	ManejadorBits manejadorBits;

	unsigned int numero = 15;

	bool resultadoPrueba = true;

	for(int i = 0; i < 32; i++)
	{
		int bit = obtenerBit(numero, i);
		if ((i < 28) && (bit != 0)){
			resultadoPrueba = false;
		}

		if ((i >= 28) && (bit != 1))
		{
			resultadoPrueba = false;
		}
	}

	if (resultadoPrueba)
	{
		cout << "OK";
	} else {
		cout << "not working";
	}
}

#endif /* PRUEBAMANEJADORBITS_H_ */
